#ifndef GAMEENGINE_GEOMETRY_COORDINATESYSTEMS_TRANSFORMER2D_H
#define GAMEENGINE_GEOMETRY_COORDINATESYSTEMS_TRANSFORMER2D_H

#include <GameEngine/Geometry/geometry_settings.h>

#include <GameEngine/Geometry/Location/point2d.h>
#include <GameEngine/Geometry/Location/vector2d.h>
#include <GameEngine/Geometry/Location/vector3d.h>


#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif

namespace Transformer2D {
	//! Index in the 3x2 matrix of a two-dimensional transformer
	enum IndexRow {
		//! First index
		FirstRow = 0,
		//! Second index
		SecondRow = 1
	};
	//! Index in the 3x2 matrix of a two-dimensional transformer
	enum IndexColumn {
		//! First index
		FirstColumn = 0,
		//! Second index
		SecondColumn = 1,
		//! Third index
		ThirdColumn = 2
	};
}

//! Class used to transform points between two 2D coordinate systems
/*!
 *  This class is a wrapper to a two-dimensional rotation matrix followed by a point
 *  translation. It provides convenience functions that allow to build the tranformation
 *  matrix from points that are known both in the source and in the destination spaces.
 *
 @sa Class Transformer3d for 3D transformations of spatial coordinates and class
     Transformer2dOrientation for transformation of 2D orientations.
 @note Most algorithms expect floating point operations.
       Type T should therefore not be an integer type
 */
template <class T>
class Transformer2d {

public:
	Transformer2d();
	Transformer2d(const Point2d<T>& from1, const Point2d<T>& from2, const Point2d<T>& from3,
		const Point2d<T>& to1, const Point2d<T>& to2, const Point2d<T>& to3);
	Transformer2d(const Transformer2d& rhs);
	virtual ~Transformer2d();
	Transformer2d& operator=(const Transformer2d& rhs);

	bool set_transformation(const Point2d<T>& from1, const Point2d<T>& from2, const Point2d<T>& from3,
		const Point2d<T>& to1, const Point2d<T>& to2, const Point2d<T>& to3);
	bool translate(const Vector2d<T>& offset);

	Vector2d<T> column1() const;
	Vector2d<T> column2() const;
	Vector2d<T> column3() const;
	Vector3d<T> row1() const;
	Vector3d<T> row2() const;

	T matrix(Transformer2D::IndexRow row, Transformer2D::IndexColumn column) const;
	T& matrix(Transformer2D::IndexRow row, Transformer2D::IndexColumn column);

	Point2d<T> transform(const Point2d<T>& from) const;

	Transformer2d inverse(bool* ok = nil) const;

protected:
	//! Transformation matrix
	T matrix_[3][2];
};

#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif

#include <GameEngine/Geometry/CoordinateSystems/transformer2d.hpp>

#endif
